import json
import sys
from PySide6.QtWidgets import (QApplication, QDialog, QTextEdit, QTableWidgetItem, QListWidget,
                             QAbstractItemView, QLabel, QLineEdit, QPushButton, QVBoxLayout,
                             QHBoxLayout, QFormLayout, QWidget, QMessageBox, QComboBox,
                             QHeaderView, QDialogButtonBox, QListWidgetItem)
from PySide6.QtCore import Qt, QDateTime
from PySide6.QtNetwork import QNetworkReply
from PySide6.QtGui import QGuiApplication

from gui.utils.api import API
from gui.window.child_dialog.base_manager import TableWidget_Base_Datamanager, timestamp_to_string


# 任务表单对话框（支持数据集和项目搜索选择）
class TaskForm(QDialog):
    """任务表单对话框：支持按名称/描述搜索选择数据集和项目"""
    def __init__(self, task=None, datasets=None, projects=None, parent:TableWidget_Base_Datamanager=None):
        super().__init__(parent)
        self.setWindowTitle("任务信息" + (" - 编辑" if task else " - 添加"))
        self.resize(600, 500)
        
        self.task = task or {}  # 任务数据（编辑模式时传入）
        self.datasets = datasets or []  # 数据集列表（用于选择）
        self.projects = projects or []  # 项目列表（用于选择）
        
        self.init_ui()
        # 编辑模式：回显任务数据
        if task:
            self._init_edit_mode()

    def init_ui(self):
        """初始化UI"""
        main_layout = QVBoxLayout(self)
        form_layout = QFormLayout()

        # 1. 任务基本信息
        self.name_edit = QLineEdit()
        self.name_edit.setPlaceholderText("请输入任务名称")
        
        self.desc_edit = QTextEdit()
        self.desc_edit.setMaximumHeight(80)
        self.desc_edit.setPlaceholderText("请输入任务描述")
        
        # 状态选择（0:未开始 1:进行中 2:已完成 3:已暂停）
        self.status_combo = QComboBox()
        self.status_combo.addItems(["未开始", "进行中", "完成交付"])

        # 添加到表单布局
        form_layout.addRow("任务名称:", self.name_edit)
        form_layout.addRow("任务描述:", self.desc_edit)
        form_layout.addRow("任务状态:", self.status_combo)

        if not self.task:
            # 2. 数据集选择（带搜索）
            self.dataset_layout = QVBoxLayout()
            self._init_dataset_selector()

            # 3. 项目选择（带搜索）
            self.project_layout = QVBoxLayout()
            self._init_project_selector()
            form_layout.addRow("所属数据集:", self.dataset_layout)
            form_layout.addRow("所属项目:", self.project_layout)
        # 底部按钮
        button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        button_box.accepted.connect(self.accept)
        button_box.rejected.connect(self.reject)

        # 主布局
        main_layout.addLayout(form_layout)
        main_layout.addWidget(button_box)

    def _init_dataset_selector(self):
        """初始化数据集选择器（带搜索）"""
        # 搜索区
        search_layout = QHBoxLayout()
        self.dataset_name_search_edit = QLineEdit()
        self.dataset_name_search_edit.setPlaceholderText("搜索数据集名称")
        self.dataset_desc_search_edit = QLineEdit()
        self.dataset_desc_search_edit.setPlaceholderText("搜索数据集描述")
        self.dataset_search_btn = QPushButton("搜索")
        self.dataset_search_btn.clicked.connect(self.search_datasets)
        # self.dataset_search_edit.textChanged.connect(self.search_datasets)  # 实时搜索
        search_layout.addWidget(self.dataset_name_search_edit)
        search_layout.addWidget(self.dataset_desc_search_edit)
        search_layout.addWidget(self.dataset_search_btn)

        # 数据集列表
        self.dataset_list = QListWidget()
        self.dataset_list.setSelectionMode(QAbstractItemView.SingleSelection)
        self.populate_datasets()  # 初始填充

        # 添加到布局
        self.dataset_layout.addLayout(search_layout)
        self.dataset_layout.addWidget(QLabel("选择数据集:"))
        self.dataset_layout.addWidget(self.dataset_list)

    def _init_project_selector(self):
        """初始化项目选择器（带搜索）"""
        # 搜索区
        search_layout = QHBoxLayout()
        self.project_name_search_edit = QLineEdit()
        self.project_name_search_edit.setPlaceholderText("搜索项目名称")
        self.project_desc_search_edit = QLineEdit()
        self.project_desc_search_edit.setPlaceholderText("搜索项目描述")
        self.project_search_btn = QPushButton("搜索")
        self.project_search_btn.clicked.connect(self.search_projects)
        search_layout.addWidget(self.project_name_search_edit)
        search_layout.addWidget(self.project_desc_search_edit)
        search_layout.addWidget(self.project_search_btn)

        # 项目列表
        self.project_list = QListWidget()
        self.project_list.setSelectionMode(QAbstractItemView.SingleSelection)
        self.populate_projects()  # 初始填充

        # 添加到布局
        self.project_layout.addLayout(search_layout)
        self.project_layout.addWidget(QLabel("选择项目:"))
        self.project_layout.addWidget(self.project_list)

    def _init_edit_mode(self):
        """编辑模式：回显任务数据"""
        self.name_edit.setText(self.task.get("name", ""))
        self.desc_edit.setText(self.task.get("desc", ""))
        self.status_combo.setCurrentIndex(self.task.get("status", 0))
        # # 回显已选择的数据集和项目
        # if "dataset_id" in self.task:
        #     self.select_dataset_by_id(self.task["dataset_id"])
        # if "project_id" in self.task:
        #     self.select_project_by_id(self.task["project_id"])

    def populate_datasets(self, filtered_datasets={}):
        """填充数据集列表（支持过滤）"""
        self.dataset_list.clear()
        filtered_datasets = filtered_datasets.get("result",[])
        datasets_to_show = filtered_datasets or self.datasets
        
        for dataset in datasets_to_show:
            # 显示格式：名称 - 描述（便于识别）
            item_text = f"{dataset['name']} - {dataset.get('desc', '无描述')}"
            item = QListWidgetItem(item_text)
            item.setData(Qt.UserRole, dataset)  # 存储原始数据
            self.dataset_list.addItem(item)

    def populate_projects(self, filtered_projects={}):
        """填充项目列表（支持过滤）"""
        self.project_list.clear()
        filtered_projects = filtered_projects.get("result",[])
        projects_to_show = filtered_projects or self.projects
        
        for project in projects_to_show:
            # 显示格式：名称 - 描述（便于识别）
            item_text = f"{project['name']} - {project.get('desc', '无描述')}"
            item = QListWidgetItem(item_text)
            item.setData(Qt.UserRole, project)  # 存储原始数据
            self.project_list.addItem(item)

    def search_datasets(self):
        """按名称/描述搜索数据集"""
        name = self.dataset_name_search_edit.text().strip()
        desc = self.dataset_desc_search_edit.text().strip()
        self.parent().api.query_datasets(name, desc,callback=self.populate_datasets)

    def search_projects(self):
        """按名称/描述搜索项目"""
        name = self.project_name_search_edit.text().strip()
        desc = self.project_desc_search_edit.text().strip()
        self.parent().api.query_projects(name, desc,callback=self.populate_projects)

    def select_dataset_by_id(self, dataset_id):
        """根据ID选中对应的数据集"""
        for i in range(self.dataset_list.count()):
            item = self.dataset_list.item(i)
            dataset = item.data(Qt.UserRole)
            if dataset.get("id") == dataset_id:
                self.dataset_list.setCurrentItem(item)
                break

    def select_project_by_id(self, project_id):
        """根据ID选中对应的项目"""
        for i in range(self.project_list.count()):
            item = self.project_list.item(i)
            project = item.data(Qt.UserRole)
            if project.get("id") == project_id:
                self.project_list.setCurrentItem(item)
                break

    def get_data(self):
        """获取表单数据（用于提交）"""

        # 构建任务数据
        task_data = {
            "name": self.name_edit.text().strip(),
            "desc": self.desc_edit.toPlainText().strip(),
            "status": self.status_combo.currentIndex(),  # 0-3对应状态
        }

        # 编辑模式：保留任务ID
        if self.task and "id" in self.task:
            task_data["task_id"] = self.task["id"]
        else:
            # 获取选中的数据集ID
            selected_dataset = self.dataset_list.selectedItems()
            dataset_id = selected_dataset[0].data(Qt.UserRole)["id"] if selected_dataset else None
            
            # 获取选中的项目ID
            selected_project = self.project_list.selectedItems()
            project_id = selected_project[0].data(Qt.UserRole)["id"] if selected_project else None
            task_data["datasets_id"] = dataset_id
            task_data["project_id"] = project_id
            
        return task_data


# 任务管理表格
class TableWidget_Tasks_manager(TableWidget_Base_Datamanager):
    """任务管理表格：支持任务的增删改查"""
    def __init__(self, api: API):
        super().__init__(api)
        self.setWindowTitle("任务管理系统")
        self.resize(1200, 600)
        
        # 存储数据集和项目列表（用于表单选择）
        self.datasets = []
        self.projects = []
        
        # 初始化表格列（任务属性）
        self.set_table_columns([
            "ID", "任务名称", "任务描述", "状态", 
            "所属数据集", "所属项目", "创建时间", "操作"
        ])
        
        # 加载基础数据（数据集、项目、任务）

    def setup_top_buttons(self):
        """顶部按钮：添加任务"""
        self.add_button = QPushButton("添加任务")
        self.add_button.clicked.connect(self.add_task)
        self.top_button_layout.addWidget(self.add_button)
        self.top_button_layout.addStretch()

    def setup_search_fields(self):
        """搜索字段：按任务名称和描述搜索"""
        self.search_name_field = QLineEdit()
        self.search_name_field.setPlaceholderText("输入任务名称...")
        
        self.search_desc_field = QLineEdit()
        self.search_desc_field.setPlaceholderText("输入任务描述...")
        
        self.search_h1_layout.addWidget(self.search_name_field)
        self.search_h1_layout.addWidget(self.search_desc_field)
        self.search_h1_layout.addStretch()

    def load_basic_data(self):
        """加载基础数据：先加载数据集和项目，再加载任务"""
        # 1. 加载数据集（用于任务表单选择）
        self.api.query_datasets(callback=self.on_datasets_loaded)
        
        # 2. 加载项目（用于任务表单选择）
        self.api.query_projects(callback=self.on_projects_loaded)

    def on_datasets_loaded(self, response):
        """数据集加载完成回调"""
        if response.get("code") == 0:
            self.datasets = response.get("result", [])

    def on_projects_loaded(self, response):
        """项目加载完成回调"""
        if response.get("code") == 0:
            self.projects = response.get("result", [])
            # 项目加载完成后，加载任务列表
            self.load_data()

    def load_data(self):
        """加载任务列表（从API获取）"""
        query_params = self.get_query_params()
        self.api.query_tasks(**query_params, callback=self.update_table)

    def get_query_params(self):
        """构建任务查询参数（支持搜索）"""
        params = super().get_query_params()  # 基础参数（分页等）
        
        # 添加搜索条件
        params.update({
            "name": self.search_name_field.text().strip(),
            "desc": self.search_desc_field.text().strip()
        })
        return params

    def fill_table_row(self, row, task):
        """填充表格行：映射任务数据到表格列"""
        # 1. ID列（存储原始数据）
        id_item = QTableWidgetItem(str(task["id"]))
        id_item.setData(Qt.UserRole, task)  # 存储完整任务数据
        self.table.setItem(row, 0, id_item)
        
        # 2. 任务名称
        self.table.setItem(row, 1, QTableWidgetItem(task.get("name", "")))
        
        # 3. 任务描述（过长显示省略号）
        desc_item = QTableWidgetItem(task.get("desc", ""))
        desc_item.setToolTip(task.get("desc", ""))  # 鼠标悬停显示完整描述
        self.table.setItem(row, 2, desc_item)
        
        # 4. 状态（显示文本而非数字）
        status_map = ["未开始", "进行中", "已完成", "已暂停"]
        status_text = status_map[task.get("status", 0)]
        self.table.setItem(row, 3, QTableWidgetItem(status_text))
        
        # 5. 所属数据集（显示名称）
        dataset_name = self._get_dataset_name(task.get("datasets_id")) or task.get("dataset",{}).get("name") or task.get("datasets_id","未指定")
        self.table.setItem(row, 4, QTableWidgetItem(str(dataset_name)))
        
        # 6. 所属项目（显示名称）
        project_name = self._get_project_name(task.get("project_id")) or task.get("dataset",{}).get("name") or task.get("project_id","未指定")
        self.table.setItem(row, 5, QTableWidgetItem(str(project_name)))
        
        # 7. 创建时间
        create_time = timestamp_to_string(task.get("create_at", 0))
        self.table.setItem(row, 6, QTableWidgetItem(create_time))
        
        # 8. 操作按钮（编辑/删除）
        self._add_operation_buttons(row)

    def _get_dataset_name(self, dataset_id):
        """根据数据集ID获取名称（无则显示“未知”）"""
        for dataset in self.datasets:
            if dataset.get("id") == dataset_id:
                return dataset.get("name", "未知数据集")
        return ""

    def _get_project_name(self, project_id):
        """根据项目ID获取名称（无则显示“未知”）"""
        for project in self.projects:
            if project.get("id") == project_id:
                return project.get("name", "未知项目")
        return ""

    def _add_operation_buttons(self, row):
        """添加操作按钮（编辑/删除）"""
        # 编辑按钮
        edit_btn = QPushButton("编辑")
        edit_btn.clicked.connect(lambda _, r=row: self.edit_task(r))
        
        # 删除按钮
        del_btn = QPushButton("删除")
        del_btn.clicked.connect(lambda _, r=row: self.delete_task(r))
        
        # 按钮容器
        btn_widget = QWidget()
        btn_layout = QHBoxLayout(btn_widget)
        btn_layout.addWidget(edit_btn)
        btn_layout.addWidget(del_btn)
        btn_layout.setContentsMargins(2, 2, 2, 2)
        
        self.table.setCellWidget(row, 7, btn_widget)

    def add_task(self):
        """添加任务：打开任务表单"""
        # 确保数据集和项目已加载
        # if not self.datasets or not self.projects:
        #     QMessageBox.warning(self, "提示", "数据集或项目数据未加载完成，请稍后再试")
        #     return
        
        # 打开添加表单
        dialog = TaskForm(
            # datasets=self.datasets,
            # projects=self.projects,
            parent=self
        )
        if dialog.exec():
            task_data = dialog.get_data()
            # 调用API添加任务
            self.api.add_task(** task_data, callback=self.on_task_operate_success)

    def edit_task(self, row):
        """编辑任务：打开任务表单（回显数据）"""
        # 获取选中的任务数据
        task_item = self.table.item(row, 0)
        task = task_item.data(Qt.UserRole)
        
        # 打开编辑表单（传入当前任务、数据集、项目）
        dialog = TaskForm(
            task=task,
            datasets=self.datasets,
            projects=self.projects,
            parent=self
        )
        if dialog.exec():
            updated_data = dialog.get_data()
            # 调用API更新任务
            self.api.set_task(**updated_data, callback=self.on_task_operate_success)

    def delete_task(self, row):
        """删除任务：确认后调用API"""
        task_item = self.table.item(row, 0)
        task = task_item.data(Qt.UserRole)
        task_name = task.get("name", "未知任务")
        
        # 确认删除
        reply = QMessageBox.question(
            self, "确认删除",
            f"确定要删除任务「{task_name}」吗？",
            QMessageBox.Yes | QMessageBox.No
        )
        if reply == QMessageBox.Yes:
            # 调用API删除任务
            self.api.del_task(id=task["id"], callback=self.on_task_operate_success)

    def on_task_operate_success(self, response):
        """任务操作（添加/编辑/删除）成功回调"""
        if response.get("code") == 0:
            QMessageBox.information(self, "成功", response.get("message", "操作成功"))
            self.load_data()  # 刷新任务列表
        else:
            QMessageBox.critical(self, "失败", response.get("message", "操作失败"))

    def handle_upload_finished(self, reply: QNetworkReply):
        """文件上传完成处理（如需扩展文件上传功能）"""
        try:
            response_data = reply.readAll().data().decode('utf-8')
            status_code = reply.attribute(Qt.UserRole)
            
            if status_code == 200:
                QMessageBox.information(self, "成功", f"文件上传成功\n{response_data}")
                self.load_data()
            else:
                QMessageBox.warning(self, "失败", f"上传失败（{status_code}）\n{response_data}")
        except Exception as e:
            QMessageBox.critical(self, "错误", f"处理上传结果失败：{str(e)}")


if __name__ == "__main__":
    app = QApplication(sys.argv)
    # 模拟API（实际使用时替换为真实API实例）
    class MockAPI:
        def __init__(self):
            pass
        def query_datasets(self, callback):
            callback({"code":0, "result":[{"id":1, "name":"图像数据集", "desc":"图片标注数据集"}]})
        def query_projects(self, callback):
            callback({"code":0, "result":[{"id":1, "name":"人脸识别项目", "desc":"人脸识别相关"}]})
        def query_tasks(self, callback, **kwargs):
            callback({
                "code":0,
                "result":[{
                    "id":1, "name":"标注任务1", "desc":"标注图像",
                    "status":1, "dataset_id":1, "project_id":1,
                    "create_at":QDateTime.currentSecsSinceEpoch()
                }],
                "page_total":1, "page":1
            })
        def add_task(self, callback, **kwargs):
            callback({"code":0, "message":"任务添加成功"})
        def update_task(self, callback, **kwargs):
            callback({"code":0, "message":"任务更新成功"})
        def delete_task(self, callback, **kwargs):
            callback({"code":0, "message":"任务删除成功"})
    
    window = TableWidget_Tasks_manager(api=MockAPI())
    window.show()
    sys.exit(app.exec())